package com.estar.integaration.Parser;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.estar.integaration.DS.Vertex;
import com.estar.integaration.Util.ExcelReader.DataListener;
import com.estar.integaration.Util.ExcelReader.MaterialListItem;
import com.estar.integaration.Util.Util;
import com.estar.integaration.entity.moneyEntity.MaterialComposition;
import com.estar.integaration.entity.moneyEntity.MaterialMoney;
import io.swagger.models.auth.In;

import java.io.*;
import java.util.*;

/**
 * Author: YJL
 * Date: 2021/12/16 22:53
 * 物料清单表
 **/
public class MaterialCompositionParse  {
  //矩阵中的先后次序
  public List<String> matrixEdgeList = new LinkedList<>();
  public Vertex[] vertexList;


  /**
   * 把Excel解析成Content
   * @param excelAddress
   * @return
   */
  public List<List<Object>> parseExcel2Content(String excelAddress){
    ExcelReader excelReader = null;
    List<List<Object>> content = null;
    try(InputStream inputStream = new FileInputStream(new File(excelAddress))){
        excelReader = ExcelUtil.getReader(inputStream,0);
        content = excelReader.read(1,excelReader.getRowCount());
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return content;
  }

  /**
   * 使用EasyExcel把Excel解析成Content
   * @param
   * @return
   */
  public List<MaterialListItem> parseeasyExcel2Content(String address){
      List<MaterialListItem> content = new ArrayList<>();

      String file = address;
      try {
        EasyExcel.read(file,MaterialListItem.class,new DataListener(content))
            .sheet(0)
            .headRowNumber(1)
            .doRead();
      }catch (Exception e){
          e.printStackTrace();
      }

      return content;
  }




  /**
   * 解析Content到矩阵
   * @param content
   * @return
   */
  public Integer[][] parseContent2Matrix(List<List<Object>> content){
    List<MaterialComposition> materialCompositionLinkedList = new LinkedList<>();//记录指向关系
    Integer[][] edgesMatrix = null;//右上角为横到竖，左下角为竖到横
    Set<String> materialCodeSet = new LinkedHashSet<>();

    String theseParentCode = "";//当前空着的物料的父物料号
    for(List<Object> list : content){
      String parentCode = String.valueOf(list.get(4));
      String materialCode = String.valueOf(list.get(9));
      if(parentCode == null || parentCode.equals("null") || parentCode == "null" || parentCode.length() < 1 || parentCode.equals("")){
        parentCode = theseParentCode;
      }else {
        theseParentCode = parentCode;
      }
      MaterialComposition materialComposition = new MaterialComposition(parentCode,materialCode);
      materialCompositionLinkedList.add(materialComposition);
      materialCodeSet.add(parentCode);
      materialCodeSet.add(materialCode);
    }
    List<String> materialCodenoRepeatList = new ArrayList<>();//无重复所有物料号list
    materialCodenoRepeatList.addAll(materialCodeSet);
    //用无重复物料号(和矩阵同序)制作一个矩阵点List
    vertexList = new Vertex[materialCodenoRepeatList.size()];
    for(int i = 0; i < materialCodenoRepeatList.size() ; i++){
      vertexList[i] = new Vertex(materialCodenoRepeatList.get(i));
    }
    matrixEdgeList = materialCodenoRepeatList;
    Integer listSize = materialCodenoRepeatList.size();
    edgesMatrix = new Integer[listSize][listSize];

    for(int i = 0; i < edgesMatrix.length; i++){
      for(int j = 0; j < edgesMatrix.length;j++)
        edgesMatrix[i][j] = 0;
    }

    //把指向关系写入矩阵
    for(int i = 0; i < materialCompositionLinkedList.size() ; i++){
      String parentCode = materialCompositionLinkedList.get(i).getParentMaterialCode();
      String materialCode = materialCompositionLinkedList.get(i).getMaterialCode();
      int y = materialCodenoRepeatList.indexOf(materialCode);//起点者
      int x = materialCodenoRepeatList.indexOf(parentCode);//终点
      edgesMatrix[y][x] = 1;
    }
    return edgesMatrix;
  }


  /**
   * 解析Content到邻接表
   * @param content
   * @return
   */
  public LinkedList<LinkedList<Integer>> parseContent2LinkedListMatrix(List<MaterialListItem> content){
    LinkedList<LinkedList<Integer>> indexList = new LinkedList<>();
    List<MaterialComposition> materialCompositionLinkedList = new LinkedList<>();//记录指向关系
    Integer[][] edgesMatrix = null;//右上角为横到竖，左下角为竖到横
    Set<String> materialCodeSet = new LinkedHashSet<>();

    String theseParentCode = "";//当前空着的物料的父物料号
    for(MaterialListItem m : content){
      String parentCode = m.getMaterialCode();
      String materialCode = m.getMaterialChildCode();
      if(parentCode == null || parentCode.equals("null") || parentCode == "null" || parentCode.length() < 1 || parentCode.equals("")){
        parentCode = theseParentCode;
      }else {
        theseParentCode = parentCode;
      }
      MaterialComposition materialComposition = new MaterialComposition(parentCode,materialCode);
      materialCompositionLinkedList.add(materialComposition);
      materialCodeSet.add(parentCode);
      materialCodeSet.add(materialCode);
    }
    List<String> materialCodenoRepeatList = new ArrayList<>();//无重复所有物料号list
    materialCodenoRepeatList.addAll(materialCodeSet);
    //用无重复物料号(和矩阵同序)制作一个矩阵点List
    vertexList = new Vertex[materialCodenoRepeatList.size()];
    for(int i = 0; i < materialCodenoRepeatList.size() ; i++){
      vertexList[i] = new Vertex(materialCodenoRepeatList.get(i));
    }
    matrixEdgeList = materialCodenoRepeatList;
    Integer listSize = materialCodenoRepeatList.size();
    //初始化邻接链表
    for(int i = 0; i < listSize ; i++){
      LinkedList linkedList = new LinkedList();
      indexList.add(linkedList);
    }
    for(int i = 0 ; i < materialCompositionLinkedList.size() ;i++){
      String parentCode = materialCompositionLinkedList.get(i).getParentMaterialCode();
      String materialCode = materialCompositionLinkedList.get(i).getMaterialCode();
      int y = materialCodenoRepeatList.indexOf(materialCode);//起点者
      int x = materialCodenoRepeatList.indexOf(parentCode);//终点
      indexList.get(y).add(x);
    }
//    edgesMatrix = new Integer[listSize][listSize];
//    for(int i = 0; i < edgesMatrix.length; i++){
//      for(int j = 0; j < edgesMatrix.length;j++)
//        edgesMatrix[i][j] = 0;
//    }
//    //把指向关系写入矩阵
//    for(int i = 0; i < materialCompositionLinkedList.size() ; i++){
//      String parentCode = materialCompositionLinkedList.get(i).getParentMaterialCode();
//      String materialCode = materialCompositionLinkedList.get(i).getMaterialCode();
//      int y = materialCodenoRepeatList.indexOf(materialCode);//起点者
//      int x = materialCodenoRepeatList.indexOf(parentCode);//终点
//      edgesMatrix[y][x] = 1;
//    }
    return indexList;
  }



  /**
   * 输出邻接矩阵
   * @param excelAddress
   * @return
   */
  public Integer[][] parseExcel2Matrix(String excelAddress){
    List<MaterialComposition> materialCompositionLinkedList = new LinkedList<>();//记录指向关系
    Integer[][] edgesMatrix = null;//右上角为横到竖，左下角为竖到横
    ExcelReader excelReader = null;
    List<List<Object>> content = null;
    Set<String> materialCodeSet = new LinkedHashSet<>();

    //解析出一个物料号的无重复set
    try(InputStream inputStream = new FileInputStream(new File(excelAddress))){
      String theseParentCode = "";//当前空着的物料的父物料号
      excelReader = ExcelUtil.getReader(inputStream,0);
      content = excelReader.read(1,excelReader.getRowCount());
      for(List<Object> list : content){
        String parentCode = String.valueOf(list.get(4));
        String materialCode = String.valueOf(list.get(9));
        if(parentCode == null || parentCode.equals("null") || parentCode == "null" || parentCode.length() < 1 || parentCode.equals("")){
          parentCode = theseParentCode;
        }else {
          theseParentCode = parentCode;
        }
        MaterialComposition materialComposition = new MaterialComposition(parentCode,materialCode);
        materialCompositionLinkedList.add(materialComposition);
        materialCodeSet.add(parentCode);
        materialCodeSet.add(materialCode);
      }
      List<String> materialCodenoRepeatList = new ArrayList<>();//无重复所有物料号list
      materialCodenoRepeatList.addAll(materialCodeSet);
      //用无重复物料号(和矩阵同序)制作一个矩阵点List
      vertexList = new Vertex[materialCodenoRepeatList.size()];
      for(int i = 0; i < materialCodenoRepeatList.size() ; i++){
        vertexList[i] = new Vertex(materialCodenoRepeatList.get(i));
      }
      matrixEdgeList = materialCodenoRepeatList;
      Integer listSize = materialCodenoRepeatList.size();
      edgesMatrix = new Integer[listSize][listSize];

      for(int i = 0; i < edgesMatrix.length; i++){
        for(int j = 0; j < edgesMatrix.length;j++)
          edgesMatrix[i][j] = 0;
      }

      //把指向关系写入矩阵
      for(int i = 0; i < materialCompositionLinkedList.size() ; i++){
        String parentCode = materialCompositionLinkedList.get(i).getParentMaterialCode();
        String materialCode = materialCompositionLinkedList.get(i).getMaterialCode();
        int y = materialCodenoRepeatList.indexOf(materialCode);//起点者
        int x = materialCodenoRepeatList.indexOf(parentCode);//终点
        edgesMatrix[y][x] = 1;
      }

      return edgesMatrix;

    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }


  public Integer[][] getIndexMatrix(Integer[][] allMatrix){
    List<List<Integer>> allLineList = new ArrayList<>();
    Integer[][] indexMatrix = new Integer[allMatrix.length][allMatrix.length];
    for(int i = 0; i < allMatrix.length ;i++){
      List<Integer> oneLine = new ArrayList<>();
      for(int j = 0; j < allMatrix[i].length; j++){
        if(allMatrix[i][j] == 1){
          oneLine.add(j);
        }
      }
      allLineList.add(oneLine);
      allMatrix[i] = null;//释放掉
    }
    System.gc();//释放掉
    for(int i = 0; i < allLineList.size();i++){
      Integer[] oneLineArray = new Integer[allLineList.get(i).size()];
      for(int j = 0; j < allLineList.get(i).size();j++){
        oneLineArray[j] = allLineList.get(i).get(j);
      }
      indexMatrix[i] = oneLineArray;
    }

    return indexMatrix;
  }





  public Vertex[] getVertexList() {
    return vertexList;
  }

  public void setVertexList(Vertex[] vertexList) {
    this.vertexList = vertexList;
  }

  public List<String> getMatrixEdgeList() {
    return matrixEdgeList;
  }

  public List<MaterialComposition> parseExcel(String excelAddress) {

    List<MaterialComposition> materialCompositionLinkedList = new LinkedList<>();

    ExcelReader excelReader = null;
    List<List<Object>> content = null;

    try(InputStream inputStream = new FileInputStream(new File(excelAddress))){
      excelReader = ExcelUtil.getReader(inputStream,0);
      content = excelReader.read(1,excelReader.getRowCount());

      String theseParentCode = "";//当前父物料号

      for(List<Object> list : content){

        MaterialComposition materialComposition = new MaterialComposition();

        String parentCode = String.valueOf(list.get(4));
        String materialCode = String.valueOf(list.get(9));
        if(parentCode == null || parentCode.equals("null") || parentCode == "null" || parentCode.length() < 1 || parentCode.equals("")){
          parentCode = theseParentCode;
        }else {
          theseParentCode = parentCode;
        }
        materialComposition.setParentMaterialCode(parentCode);
        materialComposition.setMaterialCode(materialCode);
//        materialComposition.setMmid("");
        materialCompositionLinkedList.add(materialComposition);
      }

      return materialCompositionLinkedList;

    } catch (FileNotFoundException e) {

      e.printStackTrace();

    } catch (IOException e) {

      e.printStackTrace();

    }

    return null;

  }

  /**
   * 从List内循环出所有子物料作为key，所有父物料的List作为Value的HashMap
   * @param materialCompositionList
   * @return
   */
  public HashMap<String,List<String>> getCMaterilPMaterialListHashMap(List<MaterialComposition> materialCompositionList){
    HashMap<String,List<String>> CFHashMap = new HashMap<>();//子物料和多个父物料list对应的HashMap
    //记录Hash<> 子物料对应的所有的父物料
    for(MaterialComposition m : materialCompositionList){
      if(m == null || m.getMaterialCode() == null || m.getParentMaterialCode() == null){
        continue;
      }
      if(CFHashMap.containsKey(m.getMaterialCode())){
        List<String> parentMaterailCodeList = CFHashMap.get(m.getMaterialCode()); //父物料号List
        parentMaterailCodeList.add(m.getParentMaterialCode());
      }else {
        List<String> parentMaterialCodeList = new LinkedList<>();
        parentMaterialCodeList.add(m.getParentMaterialCode());
        CFHashMap.put(m.getMaterialCode(),parentMaterialCodeList);
      }
    }
    return CFHashMap;
  }



}
